<template>
  <div class="home">
    <a-upload-dragger
      name="file"
      :beforeUpload="beforeUploadHandler"
      :multiple="true"
    >
      <p class="ant-upload-drag-icon">
        <inbox-outlined></inbox-outlined>
      </p>
      <p class="ant-upload-text divider">→→→ 点击 OR 拖拽 可以上传文件 ←←←</p>
    </a-upload-dragger>

    <a-divider class="divider">↓↓↓ 点击上面的按钮选择上传文件 👆👆👆</a-divider>

    <ul class="_scrollbar">
      <a-empty
        description="暂无数据, 请拖拽 OR 点击上传文件"
        v-if="allProgress.length === 0"
      />
      <li
        v-else
        v-for="item in allProgress"
        :key="item.uniqueCode"
        :class="item.type === UploadProgressState.Canceled ? 'del' : ''"
      >
        <h4>{{ item.fileName }}</h4>
        <div class="detail">
          <a-progress :percent="item.progress" class="margin" />
          <close-outlined
            v-if="isDisplayDeleteIcon(item.type)"
            @click="cancelProgressHandler(item.uniqueCode)"
            class="margin margin-left-15"
          />
          <div v-if="isRunProcessHandler(item.type)">
            <caret-left-outlined
              @click="pauseProgressHandler(item.uniqueCode)"
              class="margin"
              v-if="UploadProgressState.Pause == item.type"
            />
            <pause-outlined
              @click="pauseProgressHandler(item.uniqueCode)"
              v-else
            />
          </div>
        </div>
        <div class="detail1">
          <div class="left">
            <span>（{{ item.stateDesc }}）</span>
            <span v-show="isDisplayNetworkSpeed(item.type)">{{
              computeNetworkSpeedHandler(item.networkSpeed)
            }}</span>
            <span class="split" v-show="isDisplayNetworkSpeed(item.type)"
              >-</span
            >
            <span>
              {{ computeFileSizeHandler(item.downSize) }}/{{
                computeFileSizeHandler(item.fileSize)
              }}
            </span>
          </div>
          <div class="right" v-if="isDisplayRemainingTimeHandler(item.type)">
            <span>{{ computeRemainingTimeHandler(item.remainingTime) }}</span>
          </div>
        </div>
      </li>
    </ul>
  </div>
</template>

<script lang="ts" setup>
import {
  toFixedHandler,
  uploadHandler,
  UploadProgressState,
} from "@/utils/uploader";
import {
  CaretLeftOutlined,
  CloseOutlined,
  InboxOutlined,
  PauseOutlined,
} from "@ant-design/icons-vue";
import { useBigFileUpload } from "@/hooks/useBigFileUpload";
import {
  getFileReq,
  listFilesReq,
  mergeUploadReq,
  sectionUploadReq,
  verifyFileExistReq,
} from "@/api/upload";

const [allProgress, cancelProgressHandler, pauseProgressHandler] =
  useBigFileUpload(true);
const ONE_KB_CONST = 1024;
// 一小时 多少  秒
const ONE_HOUR = 3600;

uploadHandler.config({
  persist: true,
  maxHashNameCount: 0,
  concurrentLimit: 100,
  baseNetworkSpeed: 10 * 1024,
  req: {
    listFilesReq,
    sectionUploadReq,
    mergeUploadReq,
    verifyFileExistReq,
  },
});

/**
 * 计算 网速 大小
 *
 * @author lihh
 * @param size 网速大小
 */
function computeNetworkSpeedHandler(size: number): string {
  size = size / ONE_KB_CONST;
  if (size < ONE_KB_CONST) return `${toFixedHandler(size, 0)}KB/s`;
  return `${toFixedHandler(size / ONE_KB_CONST, 1)}M/s`;
}

/**
 * 是否显示网速
 *
 * @author lihh
 * @param state 当前状态
 */
function isDisplayNetworkSpeed(state: UploadProgressState) {
  return [
    UploadProgressState.Uploading,
    UploadProgressState.Merge,
    UploadProgressState.BreakPointUpload,
    UploadProgressState.RefreshRetry,
  ].includes(state);
}

/**
 * 是否显示 删除按钮
 *
 * @author lihh
 * @param currentState 当前状态
 */
function isDisplayDeleteIcon(currentState: UploadProgressState): boolean {
  return ![UploadProgressState.Canceled].includes(currentState);
}

/**
 * 计算 文件大小
 *
 * @author lihh
 * @param fileSize
 */
function computeFileSizeHandler(fileSize: number) {
  if (fileSize <= ONE_KB_CONST) return `${fileSize}B`;

  // 先转换为 kb
  const kbSize = fileSize / ONE_KB_CONST;

  // 判断是否 1M 以内
  if (fileSize < ONE_KB_CONST * ONE_KB_CONST)
    return `${toFixedHandler(kbSize, 0)}KB`;

  const mbSize = kbSize / ONE_KB_CONST;
  return `${toFixedHandler(mbSize, 0)}M`;
}

/**
 * 是否运行进度
 *
 * @author lihh
 * @param currentState 表示运行的状态
 */
function isRunProcessHandler(currentState: UploadProgressState) {
  return [
    UploadProgressState.PauseRetry,
    UploadProgressState.Pause,
    UploadProgressState.Uploading,
  ].includes(currentState);
}

/**
 * 是否显示剩余的时间
 *
 * @author lihh
 * @param currentState 当前状态
 */
function isDisplayRemainingTimeHandler(currentState: UploadProgressState) {
  return ![
    UploadProgressState.Merge,
    UploadProgressState.Done,
    UploadProgressState.RetryFailed,
    UploadProgressState.Canceled,
    UploadProgressState.QuickUpload,
    UploadProgressState.RequestError,
  ].includes(currentState);
}

/**
 * 表示 计算剩余时间
 *
 * @author lihh
 * @param remainingTime 剩余时间
 */
function computeRemainingTimeHandler(remainingTime: number) {
  // 这里设置 秒 的时候
  if (remainingTime < 60) return `剩余 ${toFixedHandler(remainingTime, 0)}秒`;

  // 是否满足 一个小时
  if (remainingTime < ONE_HOUR)
    return `剩余 ${toFixedHandler(remainingTime / 60, 0)}分钟${toFixedHandler(remainingTime % 60, 0)}秒`;

  // 满足小时 以及分钟
  const h = (remainingTime / ONE_HOUR) | 0,
    m = (remainingTime - h * ONE_HOUR) % 60 | 0;

  return `剩余 ${h}小时${m}分钟`;
}

/**
 * 这里是上传文件的事件
 *
 * @author lihh
 * @param file 单个文件
 */
async function beforeUploadHandler(file: File) {
  // 表示 不同的 code
  const [baseDir, fileName] = await uploadHandler(file);
  console.log(baseDir, fileName)
  await getFileReq(baseDir);
  return false;
}
</script>

<style lang="less" scoped>
.del {
  text-decoration: line-through;
}

.ant-table-body::-webkit-scrollbar,
._scrollbar::-webkit-scrollbar,
.innerBox::-webkit-scrollbar {
  width: 2px;
  height: 2px;
}

.ant-table-body::-webkit-scrollbar-thumb,
._scrollbar::-webkit-scrollbar-thumb,
.innerBox::-webkit-scrollbar-thumb {
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 5px #004a77;
  background: #004a77;
}

.ant-table-body::-webkit-scrollbar-track,
._scrollbar::-webkit-scrollbar-track,
.innerBox::-webkit-scrollbar-track {
  -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  border-radius: 0;
  background: rgba(0, 0, 0, 0.1);
}

h1,
h2,
h3,
h4,
h5 {
  margin: 0;
}

.margin-left-15 {
  margin-left: 15px !important;
}

.home {
  background: white;
  width: 700px;
  margin: auto;

  ::v-deep(.ant-upload-list-item) {
    display: none;
  }

  .divider {
    text-decoration: underline;
    font-style: italic;
    font-weight: bold;
  }

  ul,
  li {
    list-style: none;
  }

  li {
    margin-bottom: 10px;

    h5 {
      margin-top: 5px;
      padding-left: 10px;
    }
  }

  ul {
    margin: 0 auto;
    border: 1px solid #ccc;
    padding: 20px;
    border-radius: 10px;
    min-height: 750px;
    max-height: 750px;
    overflow-x: hidden;
    overflow-y: auto;

    .detail {
      display: flex;
      align-items: center;

      .margin {
        margin: 0 5px 0 0;
      }
    }

    .detail1 {
      display: flex;
      justify-content: space-between;
      font-size: 12px;
      margin: 5px 70px 0 0;

      .split {
        margin: 0 5px;
      }
    }
  }
}
</style>
